#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include <iostream>
#include <algorithm>

class String
{
	static const int defaultcapacity = 8;
public:
	String():_str(new char[defaultcapacity + 1]),_size(0), _capacity(defaultcapacity) {}
	String(int n, char ch)
	{
		_str = new char[n + 1];
		_size = n;
		_capacity = n;
		int pos = 0;
		for ( ;pos < n; pos++)
			_str[pos] = ch;
		_str[pos] = 0;
	}

	String(const String& s):_size(0), _capacity(0), _str(nullptr)
	{
		Resize(s._size);
		for (int i = 0; i < s._size; i++)
			_str[i] = s._str[i];
		_size = s._size;
	}

	String& operator=(const String& s)
	{
		String tmp(s);
		Swap(tmp);

		return *this;
	}

	void insert(char ch, size_t pos)
	{
		if (pos >= 0 && pos <= _size)
		{
			if (pos == _size && _size + 1 <= _capacity)
			{
				_str[pos] = ch;
				_str[_size + 1] = 0;
			}
			else
			{
				String tmp;
				size_t size = _size + 1 > _capacity ? _size * 2 : _capacity;
				tmp.Reserve(size);
				int i = 0;
				while (i != pos)
				{
					tmp._str[i] = _str[i];
					i++;
				}
				tmp._str[i] = ch;
				i++;
				while (i - 1 < _size)
				{
					tmp._str[i] = _str[i - 1];
					i++;
				}
				tmp._str[i] = 0;
				tmp._size = i;

				Swap(tmp);
			}
			_size++;
		}
	}

	void Swap(String& s)
	{
		std::swap(_str, s._str);
		std::swap(_size, s._size);
		std::swap(_capacity, s._capacity);
	}

	void Reserve(size_t capacity)
	{
		if (capacity != -1 &&capacity > _capacity)
		{
			char* tmp = new char[capacity + 1];
			int pos = 0;
			for (; pos < _size; pos++)
				tmp[pos] = _str[pos];
			tmp[pos] = 0;
			_capacity = capacity;
			delete[] _str;
			_str = tmp;
		}
	}

	void Resize(size_t size)
	{
		if (size != -1)
		{
			if (size > _size)
			{
				if (size > _capacity)
					Reserve(size);
				_str[size] = 0;
			}
			else
			{
				_str[size] = 0;
			}
			_size = size;
		}
	}

	~String()
	{
		delete[] _str;
		_size = 0;
		_capacity = 0;
	}
private:
	char* _str;
	size_t _size;
	size_t _capacity;
};